package designPatterns_demo.lambda_demo;

import java.util.*;
import java.util.function.*;

public class CollectionsDemo{

    public static void main(String[] args) {

        // ArrayList
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ArrayList<String> list = new ArrayList<>(Arrays.asList("I", "love", "you", "too"));

        // forEach()
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        // 使用曾强for循环迭代
        for(String str : list){
            if(str.length()>3)
                System.out.println(str);
        }

        // 使用forEach()结合匿名内部类迭代
        list.forEach(new Consumer<String>(){
            @Override
            public void accept(String str){
                if(str.length()>3)
                    System.out.println(str);
            }
        });

        // 使用forEach()结合Lambda表达式迭代1
        list.forEach((str) -> {
            if (str.length() > 3)
                System.out.println(str);
        });

        // 使用forEach()结合Lambda表达式迭代2
        list.forEach(str -> {
            if (str.length() > 3)
                System.out.println(str);
        });

        // removeIf()
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        // 使用迭代器删除列表元素
        Iterator<String> it = list.iterator();
        while(it.hasNext()){
            if(it.next().length() > 3) // 删除长度大于3的元素
                it.remove();
        }

        // 使用removeIf()结合匿名名内部类实现
        list.removeIf(new Predicate<String>() {
            @Override
            public boolean test(String str) {
                return str.length() > 3; // 删除长度大于3的元素
            }
        });

        // 使用removeIf()结合Lambda表达式实现1
        list.removeIf(str -> {
            return str.length() > 3; // 删除长度大于3的元素
        });

        // 使用removeIf()结合Lambda表达式实现2
        list.removeIf(str -> str.length() > 3);  // 删除长度大于3的元素

        // replaceAll()
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        // 使用下标实现元素替换
        for(int i=0; i<list.size(); i++){
            String str = list.get(i);
            if(str.length()>3)
                list.set(i, str.toUpperCase());
        }

        // 使用replaceAll()方法结合匿名内部类可以实现如下：
        list.replaceAll(new UnaryOperator<String>() {
            @Override
            public String apply(String str) {
                if(str.length()>3)
                    return str.toUpperCase();
                return str;
            }
        });

        // 使用Lambda表达式实现
        list.replaceAll(str -> {
            if(str.length()>3)
                return str.toUpperCase();
            return str;
        });

        // sort()
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        // Collections.sort()方法
        Collections.sort(list, new Comparator<String>(){
            @Override
            public int compare(String str1, String str2){
                return str1.length()-str2.length();
            }
        });

        // Collections.sort()方法  结合Lambda表达式实现
        Collections.sort(list,(str1, str2) -> {
            return str1.length()-str2.length();
        });

        // 使用List.sort()方法
        list.sort(new Comparator<String>(){
            @Override
            public int compare(String str1, String str2){
                return str1.length()-str2.length();
            }
        });

        // 使用List.sort()方法, 结合Lambda表达式实现
        list.sort((str1, str2) -> str1.length()-str2.length());

        // HashMap
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        HashMap<Integer, String> map = new HashMap<>();
        map.put(1, "one");
        map.put(2, "two");
        map.put(3, "three");
        map.put(7, "seven");

        // forEach()
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        // Java7以及之前迭代Map
        for(Map.Entry<Integer, String> entry : map.entrySet()){
            System.out.println(entry.getKey() + "=" + entry.getValue());
        }

        // 使用forEach()结合匿名内部类迭代Map
        map.forEach(new BiConsumer<Integer, String>() {
            @Override
            public void accept(Integer k, String v) {
                System.out.println(k + "=" + v);
            }
        });

        // 使用forEach()结合Lambda表达式迭代Map1
        map.forEach((k, v) -> {
            System.out.println(k + "=" + v);
        });

        // 使用forEach()结合Lambda表达式迭代Map2
        map.forEach((k, v) -> System.out.println(k + "=" + v));

        // getOrDefault()
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        // 需求；假设有一个数字到对应英文单词的Map，输出4对应的英文单词，如果不存在则输出NoValue
        // 查询Map中指定的值，不存在时使用默认值

        // Java7以及之前做法
        if(map.containsKey(4)){ // 1
            System.out.println(map.get(4));
        }else{
            System.out.println("NoValue");
        }
        // Java8使用Map.getOrDefault()
        System.out.println(map.getOrDefault(4, "NoValue")); // 2

        // putIfAbsent()
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        // Java8使用Map.putIfAbsent()
        map.putIfAbsent(5, "five");

        // remove()
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        // Java8使用Map.remove()
        map.remove(5, "five");

        // replace()
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        //Java8使用Map.replace()
        map.replace(1, "three", "six");

        // replaceAll()
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        // Java7以及之前替换所有Map中所有映射关系
        for(Map.Entry<Integer, String> entry : map.entrySet()){
            entry.setValue(entry.getValue().toUpperCase());
        }

        // 使用replaceAll()结合匿名内部类实现
        map.replaceAll(new BiFunction<Integer, String, String>() {
            @Override
            public String apply(Integer k, String v) {
                return v.toUpperCase();
            }
        });

        // 使用replaceAll()结合Lambda表达式实现
        map.replaceAll((k ,v) -> v.toUpperCase());

        // merge()
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        //Java8使用Map.merge()结合匿名内部类实现
        map.merge(7, "seven", new BiFunction<String, String, String>() {
            @Override
            public String apply(String v1, String v2) {
                return v1 + v2;
            }
        });

        //Java8使用Map.merge()结合Lambda表达式实现
        map.merge(7, "seven", (v1, v2) -> v1 + v2);

        // compute()
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        // Java8使用Map.compute()结合匿名内部类实现
        map.compute(7, new BiFunction<Integer, String, String>() {
            @Override
            public String apply(Integer k, String v) {
                return v == null ? "six" : v.concat("six");
            }
        });

        // Java8使用Map.compute()结合Lambda表达式实现
        map.compute(7, (k, v) -> v == null ? "six" : v.concat("six"));

        // computeIfAbsent()
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        // Java7及以前的实现方式
        if(!map.containsKey(1)){
            map.put(1, "one");
        }

        // Java8的computeIfAbsent()结合匿名内部类实现
        map.computeIfAbsent(8, new Function<Integer, String>() {
            @Override
            public String apply(Integer k) {
                return "eight";
            }
        });

        // Java8的computeIfAbsent()结合Lambda表达式实现
        map.computeIfAbsent(8, (Integer k) -> "eight");

    }

    // computeIfPresent()
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    

}
